#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
NSA5312 通信测试界面
Communication Test Widget for NSA5312

基于export_row.txt分析的工厂校准通信序列测试:
1. OWI校准模式激活
2. 逐行逐列激活传感器
3. 写入校准密钥序列
4. 验证通信正确性
"""

import sys
import time
from PyQt5.QtWidgets import (QWidget, QVBoxLayout, QHBoxLayout, QLabel, 
                           QPushButton, QGroupBox, QGridLayout, QTextEdit, 
                           QProgressBar, QSpinBox, QCheckBox, QComboBox,
                           QMessageBox, QTableWidget, QTableWidgetItem,QLineEdit,
                           QHeaderView, QTabWidget)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
from PyQt5.QtGui import QFont, QColor, QPalette

from serial_handler import NSA5312CommandHelper
from serial_protocol import CommandCode, StatusCode

class CommunicationTestThread(QThread):
    """通信测试线程"""
    
    progress_update = pyqtSignal(int, str)  # 进度, 消息
    test_complete = pyqtSignal(bool, str)   # 成功状态, 结果消息
    sensor_status_update = pyqtSignal(int, int, str)  # 行, 列, 状态
    sensor_detail_update = pyqtSignal(int, int, str, str)  # 行, 列, 状态, 详细信息
    
    def __init__(self, command_helper, test_params):
        super().__init__()
        self.command_helper = command_helper
        self.test_params = test_params
        self.is_running = True
        
        # 校准密钥序列
        self.test_params = test_params
        
        # 标准手册方式: 向0xFF地址写入B5 A6 C9 (传统OWI激活)
        self.standard_owi_keys = [0xB5, 0xA6, 0xC9]
        
        # export_row.txt方式: NSA5312解锁密钥序列  
        self.export_owi_keys = [0x72, 0xAC, 0x5D]
    
    def run(self):
        """执行通信测试"""
        try:
            total_sensors = self.test_params['rows'] * self.test_params['cols']
            completed = 0
            
            # 步骤1: 激活OWI校准模式
            self.progress_update.emit(5, "激活OWI校准模式...")
            if not self.activate_owi_calibration():
                self.test_complete.emit(False, "OWI校准模式激活失败")
                return
            
            time.sleep(0.1)  # 短暂延时
            
            # 步骤2: 逐个测试传感器通信
            self.progress_update.emit(10, "开始传感器通信测试...")
            
            failed_sensors = []
            
            for row in range(1, self.test_params['rows'] + 1):
                if not self.is_running:
                    break
                    
                # 设置行
                if not self.set_row_control(row):
                    failed_sensors.append((row, -1))
                    continue
                
                for col in range(1, self.test_params['cols'] + 1):
                    if not self.is_running:
                        break
                    
                    completed += 1
                    progress = 10 + (completed * 80) // total_sensors
                    
                    # 设置列
                    self.progress_update.emit(progress, f"测试传感器 ({row},{col})...")
                    
                    if not self.set_col_control(col):
                        self.sensor_status_update.emit(row, col, "列控制失败")
                        failed_sensors.append((row, col))
                        continue
                    
                    # 发送校准密钥序列并验证响应
                    success, detail = self.test_sensor_communication(row, col)
                    
                    # 检查是否是24号传感器 (第3行第8列)
                    sensor_number = (row - 1) * 8 + col
                    is_sensor_24 = (sensor_number == 24)
                    
                    if success:
                        status_text = "通信正常"
                        if is_sensor_24:
                            status_text += " ✓24号"
                        self.sensor_status_update.emit(row, col, status_text)
                        self.sensor_detail_update.emit(row, col, status_text, detail)
                    else:
                        status_text = "无响应"
                        if is_sensor_24:
                            status_text = "24号无响应!"
                            detail = f"⚠️ {detail} (应该有响应!)"
                        self.sensor_status_update.emit(row, col, status_text)
                        self.sensor_detail_update.emit(row, col, status_text, detail)
                        failed_sensors.append((row, col))
                    
                    time.sleep(self.test_params['delay'] / 1000.0)  # 转换为秒
            
            # 步骤3: 生成测试报告
            self.progress_update.emit(95, "生成测试报告...")
            
            if failed_sensors:
                failure_msg = f"测试完成，{len(failed_sensors)}个传感器通信失败:\\n"
                for row, col in failed_sensors[:10]:  # 最多显示10个
                    if col == -1:
                        failure_msg += f"  行{row}: 行控制失败\\n"
                    else:
                        failure_msg += f"  ({row},{col}): 传感器通信失败\\n"
                if len(failed_sensors) > 10:
                    failure_msg += f"  ... 还有{len(failed_sensors)-10}个失败"
                
                self.test_complete.emit(False, failure_msg)
            else:
                success_msg = f"✅ 所有{total_sensors}个传感器通信测试通过！"
                self.test_complete.emit(True, success_msg)
            
            self.progress_update.emit(100, "测试完成")
            
        except Exception as e:
            self.test_complete.emit(False, f"测试异常: {str(e)}")
    
    def activate_owi_calibration(self):
        """激活OWI校准模式 (0x23)"""
        try:
            params = bytes([0x01])  # 开启校准模式
            response = self.command_helper.send_custom_command(0x23, params)
            return response.success
        except:
            return False
    
    def set_row_control(self, row_value):
        """设置行控制 (0x0A)"""
        try:
            # 直接发送行值，不需要channel参数
            params = bytes([row_value])
            response = self.command_helper.send_custom_command(0x0A, params)
            return response.success
        except:
            return False
    
    def set_col_control(self, col_value):
        """设置列控制 (0x0B)"""
        try:
            # 直接发送列值，不需要channel参数
            params = bytes([col_value])
            response = self.command_helper.send_custom_command(0x0B, params)
            return response.success
        except:
            return False
    
    def test_sensor_communication(self, row, col):
        """测试传感器通信 - 使用正确的OWI命令格式"""
        detail_info = f"位置({row},{col}): "
        
        try:
            # 选择密钥模式
            if self.test_params.get('key_mode', 'standard') == 'standard':
                keys = self.standard_owi_keys
                key_mode = "标准手册"
            else:
                keys = self.export_owi_keys  
                key_mode = "Export解锁"
            
            detail_info += f"{key_mode}模式, "
            
            # 发送OWI密钥序列 - 使用正确格式
            keys_sent = 0
            for key_byte in keys:
                # 构建正确的OWI写入命令: E1 05 1A 01 <密钥> <CRC>
                success = self.send_owi_key_command(key_byte)
                if not success:
                    detail_info += f"密钥0x{key_byte:02X}发送失败"
                    return False, detail_info
                
                keys_sent += 1
                time.sleep(0.01)  # 密钥间延时
            
            detail_info += f"发送{keys_sent}个密钥, "
            
            # 验证传感器响应：尝试读取数据
            time.sleep(0.05)  # 等待传感器处理
            
            # 尝试读取传感器状态/数据来验证通信
            try:
                read_response = self.command_helper.owi_read(2)  # 读取2字节
                if read_response.success and read_response.data and len(read_response.data) > 0:
                    # 如果能读取到数据，说明传感器确实存在并响应
                    data_bytes = read_response.data
                    data_hex = " ".join(f"{b:02X}" for b in data_bytes)
                    detail_info += f"读取响应: {data_hex}"
                    
                    # 检查数据是否有效 (不全为0x00或0xFF)
                    is_valid_response = not (all(b == 0x00 for b in data_bytes) or all(b == 0xFF for b in data_bytes))
                    
                    if is_valid_response:
                        detail_info += " (有效响应)"
                        return True, detail_info
                    else:
                        detail_info += " (无效响应)"
                        return False, detail_info
                else:
                    detail_info += "无读取响应"
                    return False, detail_info
            except Exception as read_e:
                detail_info += f"读取异常: {str(read_e)}"
                return False, detail_info
            
        except Exception as e:
            detail_info += f"通信异常: {str(e)}"
            return False, detail_info
    
    def send_owi_key_command(self, key_byte):
        """发送单个OWI密钥命令 - 正确格式"""
        try:
            # 构建命令: E1 05 1A 01 <密钥> <CRC>
            # E1 = 地址
            # 05 = 不含CRC的总字节数 (地址1 + 长度1 + 命令1 + 数据长度1 + 数据1 = 5)
            # 0F = 寄存器
            # 1A = OWI写入命令
            # 01 = 写入字节数量
            # key_byte = 密钥数据
            
            # 使用protocol的build_custom_command来构建正确的命令帧
            # 参数: [数据长度, 密钥]
            params = bytes([0X0F,0x01, key_byte])  # 01表示写入1字节，key_byte是数据
            response = self.command_helper.send_custom_command(0x1A, params)
            
            return response.success
            
        except Exception as e:
            return False
    
    def stop(self):
        """停止测试"""
        self.is_running = False

class CommunicationTestWidget(QWidget):
    """NSA5312通信测试控件"""
    
    def __init__(self, command_helper: NSA5312CommandHelper):
        super().__init__()
        self.command_helper = command_helper
        self.test_thread = None
        self.init_ui()
    
    def init_ui(self):
        """初始化UI"""
        layout = QVBoxLayout()
        
        # 创建选项卡
        tab_widget = QTabWidget()
        
        # 通信测试选项卡
        comm_test_tab = self.create_communication_test_tab()
        tab_widget.addTab(comm_test_tab, "通信测试")
        
        # 单个传感器测试选项卡
        single_test_tab = self.create_single_sensor_test_tab()
        tab_widget.addTab(single_test_tab, "单传感器测试")
        
        # 密钥序列测试选项卡
        key_test_tab = self.create_key_sequence_test_tab()
        tab_widget.addTab(key_test_tab, "密钥序列测试")
        
        layout.addWidget(tab_widget)
        self.setLayout(layout)
    
    def create_communication_test_tab(self):
        """创建通信测试选项卡"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 测试参数组
        param_group = QGroupBox("测试参数")
        param_layout = QGridLayout()
        
        # 传感器阵列大小
        param_layout.addWidget(QLabel("行数:"), 0, 0)
        self.rows_spin = QSpinBox()
        self.rows_spin.setRange(1, 8)
        self.rows_spin.setValue(8)
        param_layout.addWidget(self.rows_spin, 0, 1)
        
        param_layout.addWidget(QLabel("列数:"), 0, 2)
        self.cols_spin = QSpinBox()
        self.cols_spin.setRange(1, 8)
        self.cols_spin.setValue(8)
        param_layout.addWidget(self.cols_spin, 0, 3)
        
        # 测试延时
        param_layout.addWidget(QLabel("传感器间延时:"), 1, 0)
        self.delay_spin = QSpinBox()
        self.delay_spin.setRange(10, 1000)
        self.delay_spin.setValue(50)
        self.delay_spin.setSuffix(" ms")
        param_layout.addWidget(self.delay_spin, 1, 1)
        
        # 测试模式
        param_layout.addWidget(QLabel("测试模式:"), 1, 2)
        self.test_mode_combo = QComboBox()
        self.test_mode_combo.addItems(["完整测试", "快速测试", "故障检测"])
        param_layout.addWidget(self.test_mode_combo, 1, 3)
        
        # OWI密钥模式
        param_layout.addWidget(QLabel("OWI密钥模式:"), 2, 0)
        self.key_mode_combo = QComboBox()
        self.key_mode_combo.addItems(["标准手册 (0xFF: B5 A6 C9)", "Export序列 (0x0F: 01 72, 01 AC, 01 5D)"])
        param_layout.addWidget(self.key_mode_combo, 2, 1, 1, 3)
        
        param_group.setLayout(param_layout)
        layout.addWidget(param_group)
        
        # 控制按钮组
        control_group = QGroupBox("测试控制")
        control_layout = QHBoxLayout()
        
        self.start_test_btn = QPushButton("开始通信测试")
        self.start_test_btn.clicked.connect(self.start_communication_test)
        control_layout.addWidget(self.start_test_btn)
        
        self.stop_test_btn = QPushButton("停止测试")
        self.stop_test_btn.clicked.connect(self.stop_communication_test)
        self.stop_test_btn.setEnabled(False)
        control_layout.addWidget(self.stop_test_btn)
        
        self.clear_results_btn = QPushButton("清空结果")
        self.clear_results_btn.clicked.connect(self.clear_results)
        control_layout.addWidget(self.clear_results_btn)
        
        control_layout.addStretch()
        control_group.setLayout(control_layout)
        layout.addWidget(control_group)
        
        # 进度显示
        progress_group = QGroupBox("测试进度")
        progress_layout = QVBoxLayout()
        
        self.progress_bar = QProgressBar()
        progress_layout.addWidget(self.progress_bar)
        
        self.progress_label = QLabel("就绪")
        progress_layout.addWidget(self.progress_label)
        
        progress_group.setLayout(progress_layout)
        layout.addWidget(progress_group)
        
        # 传感器状态表格
        status_group = QGroupBox("传感器状态")
        status_layout = QVBoxLayout()
        
        self.status_table = QTableWidget()
        self.status_table.setMaximumHeight(200)
        status_layout.addWidget(self.status_table)
        
        status_group.setLayout(status_layout)
        layout.addWidget(status_group)
        
        # 测试结果
        result_group = QGroupBox("测试结果")
        result_layout = QVBoxLayout()
        
        self.result_text = QTextEdit()
        self.result_text.setMaximumHeight(150)
        self.result_text.setFont(QFont("Courier", 9))
        result_layout.addWidget(self.result_text)
        
        result_group.setLayout(result_layout)
        layout.addWidget(result_group)
        
        return widget
    
    def create_single_sensor_test_tab(self):
        """创建单传感器测试选项卡"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 传感器选择组
        sensor_group = QGroupBox("传感器选择")
        sensor_layout = QGridLayout()
        
        sensor_layout.addWidget(QLabel("行:"), 0, 0)
        self.single_row_spin = QSpinBox()
        self.single_row_spin.setRange(1, 8)
        self.single_row_spin.setValue(1)
        sensor_layout.addWidget(self.single_row_spin, 0, 1)
        
        sensor_layout.addWidget(QLabel("列:"), 0, 2)
        self.single_col_spin = QSpinBox()
        self.single_col_spin.setRange(1, 8)
        self.single_col_spin.setValue(1)
        sensor_layout.addWidget(self.single_col_spin, 0, 3)
        
        test_single_btn = QPushButton("测试单个传感器")
        test_single_btn.clicked.connect(self.test_single_sensor)
        sensor_layout.addWidget(test_single_btn, 0, 4)
        
        sensor_group.setLayout(sensor_layout)
        layout.addWidget(sensor_group)
        
        # 快速测试组
        quick_group = QGroupBox("快速测试")
        quick_layout = QGridLayout()
        
        test_owi_btn = QPushButton("测试OWI校准模式")
        test_owi_btn.clicked.connect(self.test_owi_calibration)
        quick_layout.addWidget(test_owi_btn, 0, 0)
        
        test_row_btn = QPushButton("测试行控制")
        test_row_btn.clicked.connect(self.test_row_control)
        quick_layout.addWidget(test_row_btn, 0, 1)
        
        test_col_btn = QPushButton("测试列控制")
        test_col_btn.clicked.connect(self.test_col_control)
        quick_layout.addWidget(test_col_btn, 0, 2)
        
        test_keys_btn = QPushButton("测试校准密钥")
        test_keys_btn.clicked.connect(self.test_calibration_keys)
        quick_layout.addWidget(test_keys_btn, 1, 0)
        
        quick_group.setLayout(quick_layout)
        layout.addWidget(quick_group)
        
        # 单传感器结果显示
        single_result_group = QGroupBox("测试结果")
        single_result_layout = QVBoxLayout()
        
        self.single_result_text = QTextEdit()
        self.single_result_text.setFont(QFont("Courier", 9))
        single_result_layout.addWidget(self.single_result_text)
        
        single_result_group.setLayout(single_result_layout)
        layout.addWidget(single_result_group)
        
        return widget
    
    def create_key_sequence_test_tab(self):
        """创建密钥序列测试选项卡"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        
        # 密钥序列显示组
        key_group = QGroupBox("校准密钥序列 (来自export_row.txt分析)")
        key_layout = QVBoxLayout()
        
        key_info = QTextEdit()
        key_info.setMaximumHeight(120)
        key_info.setReadOnly(True)
        key_info.setText("""NSA5312 OWI激活密钥序列:

【标准手册方式】(推荐):
时序: 上电后20ms内发送STA，100ms内发送3个密钥
密钥1: 0xFF 0xB5  (向0xFF地址写入0xB5)
密钥2: 0xFF 0xA6  (向0xFF地址写入0xA6)  
密钥3: 0xFF 0xC9  (向0xFF地址写入0xC9)

【Export序列方式】(来自export_row.txt分析):
密钥1: 0x0F 0x01 0x72  (向0x0F寄存器写入[0x01, 0x72])
密钥2: 0x0F 0x01 0xAC  (向0x0F寄存器写入[0x01, 0xAC])
密钥3: 0x0F 0x01 0x5D  (向0x0F寄存器写入[0x01, 0x5D])""")
        key_layout.addWidget(key_info)
        
        key_group.setLayout(key_layout)
        layout.addWidget(key_group)
        
        # 自定义密钥测试组
        custom_key_group = QGroupBox("自定义密钥测试")
        custom_key_layout = QGridLayout()
        
        custom_key_layout.addWidget(QLabel("寄存器地址:"), 0, 0)
        self.custom_reg_spin = QSpinBox()
        self.custom_reg_spin.setRange(0, 255)
        self.custom_reg_spin.setValue(0x0F)
        self.custom_reg_spin.setDisplayIntegerBase(16)
        self.custom_reg_spin.setPrefix("0x")
        custom_key_layout.addWidget(self.custom_reg_spin, 0, 1)
        
        custom_key_layout.addWidget(QLabel("密钥数据:"), 0, 2)
        self.custom_key_edit = QLineEdit()
        self.custom_key_edit.setText("01 72")
        self.custom_key_edit.setPlaceholderText("如: 01 72")
        custom_key_layout.addWidget(self.custom_key_edit, 0, 3)
        
        send_custom_key_btn = QPushButton("发送自定义密钥")
        send_custom_key_btn.clicked.connect(self.send_custom_key)
        custom_key_layout.addWidget(send_custom_key_btn, 0, 4)
        
        custom_key_group.setLayout(custom_key_layout)
        layout.addWidget(custom_key_group)
        
        # 批量密钥测试组
        batch_key_group = QGroupBox("批量密钥测试")
        batch_key_layout = QHBoxLayout()
        
        send_all_keys_btn = QPushButton("发送标准密钥序列")
        send_all_keys_btn.clicked.connect(self.send_all_calibration_keys)
        batch_key_layout.addWidget(send_all_keys_btn)
        
        verify_keys_btn = QPushButton("验证密钥响应")
        verify_keys_btn.clicked.connect(self.verify_key_responses)
        batch_key_layout.addWidget(verify_keys_btn)
        
        batch_key_layout.addStretch()
        batch_key_group.setLayout(batch_key_layout)
        layout.addWidget(batch_key_group)
        
        # 密钥测试结果
        key_result_group = QGroupBox("密钥测试结果")
        key_result_layout = QVBoxLayout()
        
        self.key_result_text = QTextEdit()
        self.key_result_text.setFont(QFont("Courier", 9))
        key_result_layout.addWidget(self.key_result_text)
        
        key_result_group.setLayout(key_result_layout)
        layout.addWidget(key_result_group)
        
        return widget
    
    # ======= 实现函数 =======
    
    def start_communication_test(self):
        """开始通信测试"""
        if self.test_thread and self.test_thread.isRunning():
            QMessageBox.warning(self, "警告", "测试正在进行中")
            return
        
        # 准备测试参数
        test_params = {
            'rows': self.rows_spin.value(),
            'cols': self.cols_spin.value(),
            'delay': self.delay_spin.value(),
            'mode': self.test_mode_combo.currentText(),
            'key_mode': 'standard' if self.key_mode_combo.currentIndex() == 0 else 'export'
        }
        
        # 初始化状态表格
        self.init_status_table(test_params['rows'], test_params['cols'])
        
        # 创建并启动测试线程
        self.test_thread = CommunicationTestThread(self.command_helper, test_params)
        self.test_thread.progress_update.connect(self.update_progress)
        self.test_thread.test_complete.connect(self.test_completed)
        self.test_thread.sensor_status_update.connect(self.update_sensor_status)
        self.test_thread.sensor_detail_update.connect(self.log_sensor_detail)
        
        self.test_thread.start()
        
        # 更新UI状态
        self.start_test_btn.setEnabled(False)
        self.stop_test_btn.setEnabled(True)
        
        self.log_result("开始NSA5312通信测试...")
    
    def stop_communication_test(self):
        """停止通信测试"""
        if self.test_thread:
            self.test_thread.stop()
            self.test_thread.wait(3000)  # 等待最多3秒
        
        self.start_test_btn.setEnabled(True)
        self.stop_test_btn.setEnabled(False)
        self.progress_label.setText("测试已停止")
    
    def init_status_table(self, rows, cols):
        """初始化状态表格"""
        self.status_table.setRowCount(rows)
        self.status_table.setColumnCount(cols)
        
        # 设置表头
        row_headers = [f"行{i+1}" for i in range(rows)]
        col_headers = [f"列{i+1}" for i in range(cols)]
        self.status_table.setVerticalHeaderLabels(row_headers)
        self.status_table.setHorizontalHeaderLabels(col_headers)
        
        # 初始化所有单元格
        for row in range(rows):
            for col in range(cols):
                item = QTableWidgetItem("待测")
                item.setTextAlignment(Qt.AlignCenter)
                item.setBackground(QColor(240, 240, 240))
                self.status_table.setItem(row, col, item)
        
        # 自适应列宽
        self.status_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
    
    def update_progress(self, progress, message):
        """更新进度"""
        self.progress_bar.setValue(progress)
        self.progress_label.setText(message)
    
    def update_sensor_status(self, row, col, status):
        """更新传感器状态"""
        if row > 0 and col > 0:  # 1-based to 0-based
            item = self.status_table.item(row-1, col-1)
            if item:
                item.setText(status)
                
                # 根据状态设置颜色
                if "正常" in status:
                    item.setBackground(QColor(144, 238, 144))  # 浅绿色
                elif "失败" in status or "无响应" in status:
                    item.setBackground(QColor(255, 182, 193))  # 浅红色
                else:
                    item.setBackground(QColor(255, 255, 224))  # 浅黄色
    
    def log_sensor_detail(self, row, col, status, detail):
        """记录传感器详细信息"""
        self.log_result(detail)
    
    def test_completed(self, success, message):
        """测试完成"""
        self.start_test_btn.setEnabled(True)
        self.stop_test_btn.setEnabled(False)
        
        if success:
            self.log_result(f"✅ {message}")
        else:
            self.log_result(f"❌ {message}")
        
        QMessageBox.information(self, "测试完成", message)
    
    def test_single_sensor(self):
        """测试单个传感器"""
        row = self.single_row_spin.value()
        col = self.single_col_spin.value()
        
        self.log_single_result(f"测试传感器 ({row},{col})...")
        
        try:
            # 1. 激活OWI校准模式
            params = bytes([0x01])
            response = self.command_helper.send_custom_command(0x23, params)
            if not response.success:
                self.log_single_result("❌ OWI校准模式激活失败")
                return
            
            # 2. 设置行
            params = bytes([row])
            response = self.command_helper.send_custom_command(0x0A, params)
            if not response.success:
                self.log_single_result(f"❌ 行{row}设置失败")
                return
            
            # 3. 设置列
            params = bytes([col])
            response = self.command_helper.send_custom_command(0x0B, params)
            if not response.success:
                self.log_single_result(f"❌ 列{col}设置失败")
                return
            
            # 4. 发送校准密钥序列
            calibration_keys = [
                [0x01, 0x72],
                [0x01, 0xAC],
                [0x01, 0x5D]
            ]
            
            for i, key_data in enumerate(calibration_keys):
                reg_addr = 0x0F
                full_data = bytes([reg_addr] + key_data)
                
                response = self.command_helper.owi_write(full_data)
                if response.success:
                    self.log_single_result(f"✅ 密钥{i+1}发送成功: {' '.join(f'{b:02X}' for b in full_data)}")
                else:
                    self.log_single_result(f"❌ 密钥{i+1}发送失败: {response.error_msg}")
                    return
                
                time.sleep(0.01)
            
            self.log_single_result(f"✅ 传感器 ({row},{col}) 通信测试通过")
            
        except Exception as e:
            self.log_single_result(f"❌ 测试异常: {str(e)}")
    
    def test_owi_calibration(self):
        """测试OWI校准模式"""
        try:
            params = bytes([0x01])  # 开启校准模式
            response = self.command_helper.send_custom_command(0x23, params)
            
            if response.success:
                self.log_single_result("✅ OWI校准模式激活成功")
            else:
                self.log_single_result(f"❌ OWI校准模式激活失败: {response.error_msg}")
        except Exception as e:
            self.log_single_result(f"❌ OWI校准模式测试异常: {str(e)}")
    
    def test_row_control(self):
        """测试行控制"""
        try:
            row = self.single_row_spin.value()
            params = bytes([row])
            response = self.command_helper.send_custom_command(0x0A, params)
            
            if response.success:
                self.log_single_result(f"✅ 行{row}控制成功")
            else:
                self.log_single_result(f"❌ 行{row}控制失败: {response.error_msg}")
        except Exception as e:
            self.log_single_result(f"❌ 行控制测试异常: {str(e)}")
    
    def test_col_control(self):
        """测试列控制"""
        try:
            col = self.single_col_spin.value()
            params = bytes([col])
            response = self.command_helper.send_custom_command(0x0B, params)
            
            if response.success:
                self.log_single_result(f"✅ 列{col}控制成功")
            else:
                self.log_single_result(f"❌ 列{col}控制失败: {response.error_msg}")
        except Exception as e:
            self.log_single_result(f"❌ 列控制测试异常: {str(e)}")
    
    def test_calibration_keys(self):
        """测试校准密钥"""
        try:
            calibration_keys = [
                [0x01, 0x72],
                [0x01, 0xAC], 
                [0x01, 0x5D]
            ]
            
            for i, key_data in enumerate(calibration_keys):
                reg_addr = 0x0F
                full_data = bytes([reg_addr] + key_data)
                
                response = self.command_helper.owi_write(full_data)
                if response.success:
                    self.log_single_result(f"✅ 标准密钥{i+1}发送成功")
                else:
                    self.log_single_result(f"❌ 标准密钥{i+1}发送失败: {response.error_msg}")
                    return
                
                time.sleep(0.01)
            
            self.log_single_result("✅ 所有标准校准密钥发送完成")
            
        except Exception as e:
            self.log_single_result(f"❌ 校准密钥测试异常: {str(e)}")
    
    def send_custom_key(self):
        """发送自定义密钥"""
        try:
            reg_addr = self.custom_reg_spin.value()
            key_str = self.custom_key_edit.text().strip()
            
            if not key_str:
                QMessageBox.warning(self, "错误", "请输入密钥数据")
                return
            
            # 解析十六进制数据
            key_values = [int(h, 16) for h in key_str.split()]
            full_data = bytes([reg_addr] + key_values)
            
            response = self.command_helper.owi_write(full_data)
            
            if response.success:
                self.log_key_result(f"✅ 自定义密钥发送成功: {' '.join(f'{b:02X}' for b in full_data)}")
            else:
                self.log_key_result(f"❌ 自定义密钥发送失败: {response.error_msg}")
                
        except ValueError:
            QMessageBox.warning(self, "错误", "无效的十六进制格式")
        except Exception as e:
            self.log_key_result(f"❌ 自定义密钥发送异常: {str(e)}")
    
    def send_all_calibration_keys(self):
        """发送所有标准校准密钥"""
        try:
            calibration_keys = [
                [0x01, 0x72],
                [0x01, 0xAC],
                [0x01, 0x5D]
            ]
            
            self.log_key_result("发送标准校准密钥序列...")
            
            for i, key_data in enumerate(calibration_keys):
                reg_addr = 0x0F
                full_data = bytes([reg_addr] + key_data)
                
                response = self.command_helper.owi_write(full_data)
                if response.success:
                    self.log_key_result(f"✅ 密钥{i+1}: {' '.join(f'{b:02X}' for b in full_data)} - 发送成功")
                else:
                    self.log_key_result(f"❌ 密钥{i+1}: 发送失败 - {response.error_msg}")
                    return
                
                time.sleep(0.02)  # 密钥间延时
            
            self.log_key_result("✅ 标准校准密钥序列发送完成")
            
        except Exception as e:
            self.log_key_result(f"❌ 密钥序列发送异常: {str(e)}")
    
    def verify_key_responses(self):
        """验证密钥响应"""
        try:
            # 尝试读取传感器响应
            response = self.command_helper.owi_read(3)  # 读取3字节
            
            if response.success:
                data_str = " ".join(f"{b:02X}" for b in response.data)
                self.log_key_result(f"✅ 密钥响应验证: {data_str}")
            else:
                self.log_key_result(f"❌ 密钥响应验证失败: {response.error_msg}")
                
        except Exception as e:
            self.log_key_result(f"❌ 密钥响应验证异常: {str(e)}")
    
    def clear_results(self):
        """清空结果"""
        self.result_text.clear()
        self.progress_bar.setValue(0)
        self.progress_label.setText("就绪")
        
        # 清空状态表格
        for row in range(self.status_table.rowCount()):
            for col in range(self.status_table.columnCount()):
                item = self.status_table.item(row, col)
                if item:
                    item.setText("待测")
                    item.setBackground(QColor(240, 240, 240))
    
    # ======= 辅助函数 =======
    
    def log_result(self, message):
        """记录测试结果"""
        timestamp = self.get_timestamp()
        self.result_text.append(f"[{timestamp}] {message}")
        self.auto_scroll(self.result_text)
    
    def log_single_result(self, message):
        """记录单传感器测试结果"""
        timestamp = self.get_timestamp()
        self.single_result_text.append(f"[{timestamp}] {message}")
        self.auto_scroll(self.single_result_text)
    
    def log_key_result(self, message):
        """记录密钥测试结果"""
        timestamp = self.get_timestamp()
        self.key_result_text.append(f"[{timestamp}] {message}")
        self.auto_scroll(self.key_result_text)
    
    def auto_scroll(self, text_edit):
        """自动滚动到底部"""
        cursor = text_edit.textCursor()
        cursor.movePosition(cursor.End)
        text_edit.setTextCursor(cursor)
    
    def get_timestamp(self):
        """获取时间戳"""
        from datetime import datetime
        return datetime.now().strftime("%H:%M:%S")